package org.gjy.m8.bucket;

/**
 * RateLimiterFactory – 为不同业务场景快速创建对应策略的限流器。
 *
 * @author gjy
 * @version 1.0
 * @since 2025-10-13 17:59:45
 */
public class RateLimiterFactory {

    /**
     * 支持的限流算法
     */
    public enum Strategy {
        FIXED_WINDOW,
        SLIDING_WINDOW,
        TOKEN_BUCKET,
        LEAKY_BUCKET
    }

    /**
     * 参数包装（可根据业务自行扩展）
     */
    public static class Config {
        public final Strategy strategy;
        public final long limit;       // 如 QPS、最大请求数
        public final long windowMs;    // 对于窗口类算法
        public final long burst;       // 对于 Token/Leaky Bucket 的突发容量
        public final double rate;      // 每秒令牌/泄漏速率

        private Config(Builder b) {
            this.strategy = b.strategy;
            this.limit = b.limit;
            this.windowMs = b.windowMs;
            this.burst = b.burst;
            this.rate = b.rate;
        }

        public static class Builder {
            private Strategy strategy;
            private long limit = 0;
            private long windowMs = 0;
            private long burst = 0;
            private double rate = 0;

            public Builder strategy(Strategy s) {
                this.strategy = s;
                return this;
            }

            public Builder limit(long l) {
                this.limit = l;
                return this;
            }

            public Builder windowMs(long w) {
                this.windowMs = w;
                return this;
            }

            public Builder burst(long b) {
                this.burst = b;
                return this;
            }

            public Builder rate(double r) {
                this.rate = r;
                return this;
            }

            public Config build() {
                return new Config(this);
            }
        }
    }

    /**
     * 根据配置生成对应实现的 RateLimiter（key 为业务唯一标识）。
     */
    public static <K> RateLimiter<K> create(Config cfg) {
        switch (cfg.strategy) {
            case FIXED_WINDOW:
                return new FixedWindowRateLimiter<>(cfg.limit, cfg.windowMs);
            case SLIDING_WINDOW:
                return new SlidingWindowRateLimiter<>(cfg.limit, cfg.windowMs);
            case TOKEN_BUCKET:
                return new TokenBucketRateLimiter<>(cfg.burst, cfg.rate);
            case LEAKY_BUCKET:
                return new LeakyBucketRateLimiter<>(cfg.burst, cfg.rate);
            default:
                throw new IllegalArgumentException("未知限流策略: " + cfg.strategy);
        }
    }

}